﻿using Abp.Runtime.Session;
using Abp.UI;
using Hicap.AuthorizationServer.Core.Common.EFCore;
using Hicap.AuthorizationServer.Core.Models;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Hicap.AuthorizationServer.Core.Managers
{
    public class UserRoleRelatedManager : ManagerBase<UserRoleRelated>, IUserRoleRelatedManager
    {
        public UserRoleRelatedManager(IUnitOfWork unitOfWork, IAbpSession session) : base(unitOfWork)
        {
            QueryCondition.Add(x => x.IsDeleted == false);
            CreateActions.Add(x => x.CreatorUserId = session.UserId);
            CreateActions.Add(x => x.CreationTime = DateTime.Now);
            UpdateActions.Add(x => x.LastModificationTime = DateTime.Now);
            UpdateActions.Add(x => x.LastModifierUserId = session.UserId);
            DeleteActions.Add(x => x.DeletionTime = DateTime.Now);
            DeleteActions.Add(x => x.DeleterUserId = session.UserId);
            DeleteActions.Add(x => x.IsDeleted = true);
            CreateActions.Add(IsDbExist);

            CreateCheckActions.Add(x =>
            {
                if (x.Id == 0) return true;
                Log.Warning($"UserRoleRelated CreateCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
            UpdateCheckActions.Add(x =>
            {
                if (x.Id > 0 && x.IsDeleted == false) return true;
                Log.Warning($"UserRoleRelated UpdateCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
            DeleteCheckActions.Add(x =>
            {
                if (x.IsDeleted == false) return true;
                Log.Warning($"UserRoleRelated DeleteCheck Fail : {JsonConvert.SerializeObject(x)}");
                return false;
            });
        }

        ///<summary>
        /// 重复值校验
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        private void IsDbExist(UserRoleRelated entity)
        {
            bool isDbExist = false;

            if (entity.Role != null & entity.User != null)
            {
                isDbExist = Repository.GetIncludingQuery(x => x.User, x => x.Role).Any(x => x.Role.Id == entity.Role.Id && x.User.Id == entity.User.Id);
            }

            if (isDbExist)
                throw new UserFriendlyException($"{("SameRecordIsExist")}:{("Role")},{("User")}");
        }

        public async Task<int> GetCount(Func<UserRoleRelated, bool> query)
        {
            return await Repository.CountAsync(x => query(x));
        }

        public List<Role> GetRole(int id)
        {
            IQueryable<Role> roles = Repository.GetIncludingQuery(x => x.User, x => x.Role)
                .AsNoTracking()
                .Where(x => x.User.Id == id)
                .Select(x => x.Role);
            return roles.ToList();
        }

        public IQueryable<UserRoleRelated> GetRoleAllIncluding()
        {
            return Repository.GetIncludingQuery(x => x.Role, x => x.User);
        }
    }
}